package com.gimi.cloud.bbp.client.controller;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.Base64;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.gimi.cloud.bbp.client.service.UserService;
import com.gimi.cloud.bbp.client.service.userInfo.UserInfoService;
import com.gimi.cloud.bbp.common.constant.RedisKeyConstant;
import com.gimi.cloud.bbp.common.enums.ResponseCodeEnum;
import com.gimi.cloud.bbp.common.exception.MsgException;
import com.gimi.cloud.bbp.common.utils.AESUtil;
import com.gimi.cloud.bbp.common.utils.IPUtil;
import com.gimi.cloud.bbp.common.utils.JsonUtil;
import com.gimi.cloud.bbp.common.utils.MD5;
import com.gimi.cloud.bbp.common.utils.RandomUtil;
import com.gimi.cloud.bbp.common.utils.ReflectUtils;
import com.gimi.cloud.bbp.common.utils.SHA1;
import com.gimi.cloud.bbp.common.utils.StringUtil;
import com.gimi.cloud.bbp.common.utils.Validates;
import com.gimi.cloud.bbp.common.utils.BCrypt.SwordBCrypt;
import com.gimi.cloud.bbp.common.utils.reqhead.Response;
import com.gimi.cloud.bbp.common.utils.reqhead.Util;
import com.gimi.cloud.bbp.commonService.common.CommonCoreNoticeService;
import com.gimi.cloud.bbp.commonService.redis.RedisService;
import com.gimi.cloud.bbp.commonService.sms.SmsPortal;
import com.gimi.cloud.bbp.dao.dao.core.MessageDao;
import com.gimi.cloud.bbp.dao.dao.core.MessageTemplateDao;
import com.gimi.cloud.bbp.dao.dao.sys.SysConfigDao;
import com.gimi.cloud.bbp.dto.user.UserDTO;
import com.gimi.cloud.bbp.entity.core.Message;
import com.gimi.cloud.bbp.entity.core.MessageTemplate;
import com.gimi.cloud.bbp.entity.user.User;
import com.gimi.cloud.bbp.entity.userInfo.RdUserInfoEntity;

/**
 * APP注册登录相关Contoller
 * @author  wbj
 * @date 2018-01-19
 */
@RestController
@RequestMapping("/register")
public class RegisterController {
	private UserService userService;
	private RedisService redisService;
	private CommonCoreNoticeService coreNoticeService;
	private UserInfoService userInfoService;
	private MessageTemplateDao messageTemplateDao;
	private MessageDao messageDao;
	private static Logger logger = LoggerFactory.getLogger(RegisterController.class);
	private final SysConfigDao configDao;

	@Autowired
	private RegisterController(UserService userService, UserInfoService userInfoService, MessageDao messageDao,
							   RedisService redisService, CommonCoreNoticeService coreNoticeService, MessageTemplateDao messageTemplateDao,SysConfigDao configDao) {
		this.userService = userService;
		this.redisService = redisService;
		this.coreNoticeService = coreNoticeService;
		this.userInfoService = userInfoService;
		this.messageTemplateDao = messageTemplateDao;
		this.messageDao = messageDao;
		this.configDao = configDao;
	}

	/**
	 * 验证注册号码是否可用
	 * @param request 请求
	 * @param response 返回内容
	 * @param phone 电话号码
	 */
	@RequestMapping("/checkPhoneAvailable")
	public void checkPhoneAvailable(HttpServletRequest request,HttpServletResponse response,@RequestBody String phone) {
		String phoneFormat = "^((13[\\d])|(15[0-35-9])|(18[\\d])|(147)|(17[\\d]))\\d{8}$";
		Pattern p = Pattern.compile(phoneFormat);
		Matcher m = p.matcher(phone);
		Response resp = new Response();
		ResponseCodeEnum status = null;
		if (m.matches()) {
			// 绑定该手机的用户
			User user = userService.checkPhoneAvailable(phone);
			if (user == null) {
				status = ResponseCodeEnum.SUCCESSED;
			} else {
				status = ResponseCodeEnum.ERR_PHONE_USED;
			}
		} else {
			status = ResponseCodeEnum.ERR_PHONE_INVALID;
		}
		resp.setResponseCode(status);
		Util.sendResponse(JsonUtil.toJson(resp), response);
	}

	@RequestMapping("/doRegister")
	public void doRegister(@RequestBody UserDTO params, HttpServletResponse response, HttpServletRequest request)
			throws Exception {
		Response resp = new Response();
		// 校验数据
		ResponseCodeEnum status = checkData(params);
		if (status != null) {
			resp.setResponseCode(status);
			Util.sendResponse(JsonUtil.toJson(resp), response);
			return;
		}

		// 校验验证码
		// status = checkCode(AppCommons.REGISTER_CODE_MAP, params.getPhone(),
		// params.getCode());
		String key = "uxq:verification_code:register:" + params.getMobilePhone();
		status = redisCheckCode(params.getCode(), key);
		if (status != null) {
			resp.setResponseCode(status);
			Util.sendResponse(JsonUtil.toJson(resp), response);
			return;
		}

		String ip = IPUtil.getRemortIP(request);

		// 开始注册
		// User u = userService.doRegister(model);
		// if (u != null) {
		// userService.modifyPhone(u.getUserId(), params.getPhone(), 1);
		// gmUserLocationService.insertUserPhoneLocation(u.getUserId());//增加手机归属地存储
		// resp.setResponseCode(ResponseCodeEnum.SUCCESSED,"注册成功");
		// }else{
		// resp.setResponseCode(ResponseCodeEnum.ERRORED);
		// }
		// resp.setRes_data(JSONObject.parseObject("{\"bigRedEnvelopeMoney\":
		// \"10000\"}"));
		Util.sendResponse(JsonUtil.toJson(resp), response);
	}

	/**
	 * 通过用户名密码登录
	 * @param params 登录参数
	 * @param response 响应结果
	 * @throws Exception 异常信息
	 */
	@RequestMapping("/doLoginByPassword")
	public void doLoginByPassword(@RequestBody UserDTO params, HttpServletResponse response) throws Exception {
		Response resp = new Response();
		String id = params.getMobilePhone();
		String pwd = params.getPwd();
		User user = loginValidate(id, pwd, response);
		if (user == null) {
			resp.setResponseCode(ResponseCodeEnum.ERR_PWD_NOT_CORRECT, "用户名密码不匹配");
			Util.sendResponse(JsonUtil.toJson(resp), response);
			return;
		}
		//生成用户token，并根据当前系统配置，添加到redis中
		String token = userService.createUserLoginToken(user);
		resp.setResponseCode(ResponseCodeEnum.SUCCESSED, "登录成功");
		resp.setRes_data(token);
		Util.sendResponse(JsonUtil.toJson(resp), response);
	}

	@RequestMapping("/refreshToken")
	public void refreshToken(@RequestBody UserDTO params, HttpServletResponse response) throws Exception {
		// user中需要有userId和phone字段
		User user = new User();
		user.setUserId(params.getUserId());
		user.setUserName(params.getMobilePhone());
		Response resp = new Response();
		//生成用户token，并根据当前系统配置，添加到redis中
		String token = userService.createUserLoginToken(user);
		resp.setResponseCode(ResponseCodeEnum.SUCCESSED, "刷新授权成功");
		resp.setRes_data(token);
		Util.sendResponse(JsonUtil.toJson(resp), response);
	}

	/**
	 * 忘记密码，获取验证码
	 */
	@RequestMapping("/getResetPwdCode")
	public void getInitPwdCode(@RequestBody UserDTO param, HttpServletResponse response) throws MsgException {
		Response resp = new Response();
		String identifier = param.getMobilePhone();
		if (Validates.isPhone(identifier)) {
			User user = userService.checkPhoneAvailable(identifier);
			if (user == null) {
				resp.setResponseCode(ResponseCodeEnum.ERR_USER_INVALID, "用户不存在");
				Util.sendResponse(JsonUtil.toJson(resp), response);
				return;
			}
			if (redisFixedTimeSendCode(identifier)) {
				resp.setResponseCode(ResponseCodeEnum.ACCESS_BARRED);
				Util.sendResponse(JsonUtil.toJson(resp), response);
				return;
			}
			// 创建验证码
			String createCode = RandomUtil.code();
			// 发送验证码
			sendCode(user.getMobilePhone(), createCode);
			// 插入到redis中
			insertResetPwdCodeToRedis(user.getMobilePhone(), createCode);
			resp.setResponseCode(ResponseCodeEnum.SUCCESSED, "请输入" + StringUtil.hideStr(identifier, 3, 4) + "收到的6位数字验证码");
			Util.sendResponse(JsonUtil.toJson(resp), response);
		} else if (Validates.isEmail(identifier)) {
			User user = userService.getUserByEmail(identifier);
			if (user == null) {
				resp.setResponseCode(ResponseCodeEnum.ERR_USER_INVALID, "用户不存在");
				Util.sendResponse(JsonUtil.toJson(resp), response);
				return;
			}
			// 60s内只发一次验证码
			if (redisFixedTimeSendCode(identifier)) {
				resp.setResponseCode(ResponseCodeEnum.ACCESS_BARRED);
				Util.sendResponse(JsonUtil.toJson(resp), response);
				return;
			}
			//	创建验证码
			String createCode = RandomUtil.getRandomNumString(6);
			logger.info("createCode>>>" + createCode);
			// 发送验证码
			sendCode(user.getMobilePhone(), createCode);
			// 插入到redis中
			insertResetPwdCodeToRedis(user.getMobilePhone(), createCode);
			resp.setResponseCode(ResponseCodeEnum.SUCCESSED, "请输入" + StringUtil.hideStr(identifier, 3, 3) + "信箱收到的6位数字验证码");
			Util.sendResponse(JsonUtil.toJson(resp), response);
		} else {
			resp.setResponseCode(ResponseCodeEnum.ERR_USER_INVALID, "用户名格式错误");
			Util.sendResponse(JsonUtil.toJson(resp), response);
			return;
		}
	}

	/**
	 * 校验验证码
	 * @param userDTO 用户信息
	 * @param response
	 * @throws Exception
	 */
	@RequestMapping("/doLoginByPwdCode")
	public void doLoginByPwdCode(@RequestBody UserDTO userDTO, HttpServletResponse response) throws Exception {
		logger.info("用户"+userDTO.getMobilePhone()+"通过验证码注册："+ JSON.toJSONString(userDTO));
		String identifier = userDTO.getMobilePhone();
		String code = userDTO.getCode();
		Response resp = new Response();
		Map<String, Object> map = new HashMap<>();
		String key = RedisKeyConstant.APP_VALIDATE_CODE_PREFIX +SmsPortal.LOGIN_BY_PWDCODE+":"+identifier;
//		String key = RedisKeyEnum.BBP_APP_PRE.getKey()+"verification_code:"+SmsPortal.LOGIN_BY_PWDCODE+":" + identifier;
		ResponseCodeEnum status = redisCheckCode(code, key);
		if (status != null) {
			resp.setResponseCode(status);
			Util.sendResponse(JsonUtil.toJson(resp), response);
			return;
		}
		// 此处增加一个用户的判断，如果用户不存在，则新增，如果存在，则不操作
		Boolean isHasPassword = true;
		User isUser = userService.getUserByUserName(identifier);
		if (isUser == null) {
			isUser = new User();
			ReflectUtils.copyPropertiesIgnoreNull(userDTO,isUser);
			isUser.setUserName(userDTO.getMobilePhone());
			userService.baseInset(isUser);
			isHasPassword = false;
		} else if (StringUtils.isBlank(isUser.getPwd())) {
			isHasPassword = false;
		}
		//生成用户token，并根据当前系统配置，添加到redis中
		String token = userService.createUserLoginToken(isUser);
		map.put("token", token);
		map.put("isHasPassword", isHasPassword);
		resp.setResponseCode(ResponseCodeEnum.SUCCESSED, "登录成功");
		resp.setRes_data(map);
		Util.sendResponse(JsonUtil.toJson(resp), response);
	}

	/**
	 * 校验初始化密码的验证码
	 *
	 * @throws IOException
	 */
	@RequestMapping("/doInitPassword")
	public void doInitPassword(@RequestBody UserDTO userDTO, HttpServletResponse response) throws Exception {
		String identifier = userDTO.getMobilePhone();
		String code = userDTO.getCode();
		Response resp = new Response();
		User user = new User();
		user.setMobilePhone(identifier);
		User isUser = userService.getUserByMobilePhone(user);
		if (isUser == null) {
			resp.setResponseCode(ResponseCodeEnum.ERR_USER_INVALID, "用户不存在");
			Util.sendResponse(JsonUtil.toJson(resp), response);
			return;
		}
		// 校验验证码
		String key = RedisKeyConstant.APP_PREFIX + "verification_code:initPassword:" + identifier;
		ResponseCodeEnum status = redisCheckCode(code, key);
		if (status != null) {
			resp.setResponseCode(status);
			Util.sendResponse(JsonUtil.toJson(resp), response);
			return;
		}
		// 如果验证码校验通过，则可以进行保存密码操作,先将AES加密的密码解密，然后MD5加密
		String pwd = userDTO.getPwd();
		String aesPWD = AESUtil.decrypt(pwd, AESUtil.CRYPT_KEY);
		logger.info("手机号为===" + identifier + "===aes解密为" + aesPWD);
		Map<String, String> map = JsonUtil.jsonToMap(aesPWD);
		String md5PWD = MD5.toMD5(map.get("paPassword"));
		logger.info("手机号为===" + identifier + "===MD5加密为" + md5PWD);

		isUser.setPwd(md5PWD);
		userService.modifyPwd(isUser);

		resp.setResponseCode(ResponseCodeEnum.SUCCESSED, "初始化密码成功");
		Util.sendResponse(JsonUtil.toJson(resp), response);
	}

	/**
	 * 初始化密码
	 *
	 * @throws IOException
	 */
	@RequestMapping("/initPassword")
	public void initPassword(@RequestBody UserDTO userDTO, HttpServletResponse response) throws Exception {
		String identifier = userDTO.getMobilePhone();
		Response resp = new Response();

		User user = new User();
		user.setMobilePhone(identifier);
		User isUser = userService.getUserByMobilePhone(user);
		if (isUser == null) {
			resp.setResponseCode(ResponseCodeEnum.ERR_USER_INVALID, "用户不存在");
			Util.sendResponse(JsonUtil.toJson(resp), response);
			return;
		}
		// 如果验证码校验通过，则可以进行保存密码操作,先将AES加密的密码解密，然后MD5加密
		String pwd = userDTO.getPwd();
		String cryptPWD = SwordBCrypt.hashpw(pwd);
		logger.info("手机号为===" + identifier + "===BCrypt加密为" + cryptPWD);
		isUser.setPwd(cryptPWD);
		userService.modifyPwd(isUser);

		resp.setResponseCode(ResponseCodeEnum.SUCCESSED, "初始化密码成功");
		Util.sendResponse(JsonUtil.toJson(resp), response);
	}

	/**
	 * 重置密码
	 *
	 * @throws IOException
	 */
	@RequestMapping("/resetPwd")
	public void resetPwd(@RequestBody UserDTO param, HttpServletResponse response) throws IOException {
		String identifier = param.getMobilePhone();
		String pwd = param.getPwd();
		Response resp = new Response();
		String needCheck = new String(Base64.getDecoder().decode(pwd), "utf-8");
		ResponseCodeEnum status = checkPwd(needCheck);
		if (status != null) {
			resp.setResponseCode(status);
			Util.sendResponse(JsonUtil.toJson(resp), response);
			return;
		}
		User user = null;
		if (Validates.isPhone(identifier)) {
			user = userService.checkPhoneAvailable(identifier);
		} else if (Validates.isEmail(identifier)) {
			user = userService.getUserByEmail(identifier);
		}
		if (user != null) {
			pwd = SHA1.encode(new String(Base64.getDecoder().decode(param.getPwd()), "utf-8"));
			//pwd可能需要处理下
			user.setPwd(pwd);
			userService.modifyPwd(user);
			resp.setResponseCode(ResponseCodeEnum.SUCCESSED, "重置密码成功");
			Util.sendResponse(JsonUtil.toJson(resp), response);
			return;
		} else {
			resp.setResponseCode(ResponseCodeEnum.ERR_USER_INVALID, "用户不存在");
			Util.sendResponse(JsonUtil.toJson(resp), response);
			return;
		}
	}

	/**
	 * 修改登录密码
	 *
	 * @return
	 * @throws Exception
	 */
	@RequestMapping("/modifyPwd")
	public void modifyPwd(@RequestBody UserDTO params, HttpServletResponse response) throws Exception {
		Response resp = new Response();
		if(null == params.getUserId()){
			resp.setResponseCode(ResponseCodeEnum.OPERATOR_NAME_NOT_EMPTY, "无效的用户id");
			Util.sendResponse(JsonUtil.toJson(resp), response);
			return;
		}
		User user = userService.getUserById(params.getUserId());
		if (user == null) {
			resp.setResponseCode(ResponseCodeEnum.OPERATOR_NAME_NOT_EMPTY, "无效的用户id");
			Util.sendResponse(JsonUtil.toJson(resp), response);
			return;
		}
		String new_pwd = params.getNew_pwd();
		// 判断是否有老密码
		if (StringUtil.isBlank(user.getPwd())) {
			resp.setResponseCode(ResponseCodeEnum.ERR_PWD_NOT_CORRECT, "未初始化密码，请直接初始化密码!");
			Util.sendResponse(JsonUtil.toJson(resp), response);
			return;
		}
		// 判断旧密码是否和old_pwd一致
		if (!SwordBCrypt.checkpw(params.getOld_pwd(), user.getPwd())) {
			resp.setResponseCode(ResponseCodeEnum.ERR_PWD_NOT_CORRECT, "输入的旧密码不正确");
			Util.sendResponse(JsonUtil.toJson(resp), response);
			return;
		}
		if (SwordBCrypt.checkpw(new_pwd, user.getPwd())) {
			resp.setResponseCode(ResponseCodeEnum.ERR_PWD_REPEAT, "新密码不能与原密码一致");
			Util.sendResponse(JsonUtil.toJson(resp), response);
			return;
		}

		user.setPwd(SwordBCrypt.hashpw(new_pwd));
		userService.modifyPwd(user);
		resp.setResponseCode(ResponseCodeEnum.SUCCESSED, "修改密码成功");
		Util.sendResponse(JsonUtil.toJson(resp), response);

	}

	/**
	 * 未读消息数量
	 * 
	 * @throws Exception
	 */
	@RequestMapping("/unreadMsg")
	public void unreadMsg(@RequestBody Long userId, HttpServletResponse response) throws Exception {
		// Response resp = new Response();
		// User user=getAppSessionUser(userId+"",response);
		// if(user == null){
		// return;
		// }
		// //未读消息的条数
		// int unreadCount=messageService.unreadCount(user.getUserId());
		// String msg_ids = messageService.getSysList();
		// if(msg_ids.equals("null") || msg_ids == null) {
		// msg_ids = "";
		// }
		// Map<String,Object> data = new HashMap<>();
		// data.put("msg_count", unreadCount);
		// data.put("msg_ids", msg_ids);
		// resp.setRes_data(data);
		// resp.setResponseCode(ResponseCodeEnum.SUCCESSED);
		// Util.sendResponse(JsonUtil.toJson(resp), response);
	}

	/**
	 * 获取User对象
	 *
	 * @return
	 */
	protected User getAppSessionUser(String userId, HttpServletResponse response) {
		Response resp = new Response();
		if (StringUtil.isEmpty(userId)) {
			resp.setResponseCode(ResponseCodeEnum.ERR_USER_INVALID);
			Util.sendResponse(JsonUtil.toJson(resp), response);
			return null;
		}
		User user = userService.getUserById(Integer.valueOf(userId));
		if (user == null) {
			resp.setResponseCode(ResponseCodeEnum.ERR_USER_INVALID, "用户不存在");
			Util.sendResponse(JsonUtil.toJson(resp), response);
			return null;
		}
		return user;
	}

	private ResponseCodeEnum checkData(UserDTO params) throws UnsupportedEncodingException {
		// 校验用户名（暂时没有使用到用户名，先注释掉）
		/*
		 * status = checkUsername(""); if(status != null){ return status; }
		 */
		// 校验电话号码（格式和是否已注册过）
		ResponseCodeEnum status = checkPhone(params.getMobilePhone());
		if (status != null) {
			return status;
		}
		// 校验密码(明文密码长度在6位到16位之间)
		String needCheck = new String(Base64.getDecoder().decode(params.getPwd()), "utf-8");
		status = checkPwd(needCheck);
		if (status != null) {
			return status;
		}
		// 校验邀请码（暂时没有使用到邀请码，先注释掉）
		/*
		 * status = checkInviterPhone(params.getInviter()); if(status != null){ return
		 * status; }
		 */
		return status;
	}

	/*
	 * 校验用户名格式及是否被占用
	 *
	 * @param username
	 */
	private ResponseCodeEnum checkUsername(String username) {
		ResponseCodeEnum status = null;
		if ("".equals(username)) {
			return null;// 待理解
		}
		String usernameFormat = "^(?![0-9]+$)[0-9A-Za-z\u0391-\uFFE5]{4,16}$";
		Pattern p = Pattern.compile(usernameFormat);
		Matcher m = p.matcher(username);
		if (m.matches()) {
			int count = userService.countByUserName(username);
			if (count > 0) {
				status = ResponseCodeEnum.ERR_USERNAME_USED;
			}
		} else {
			status = ResponseCodeEnum.ERR_USERNAME_INVALID;
		}
		return status;
	}

	/*
	 * 验证手机格式及是否被占用
	 *
	 * @param phone
	 */
	private ResponseCodeEnum checkPhone(String phone) {
		ResponseCodeEnum status = null;
		String phoneFormat = "^((13[\\d])|(15[0-35-9])|(18[\\d])|(147)|(17[\\d]))\\d{8}$";
		Pattern p = Pattern.compile(phoneFormat);
		Matcher m = p.matcher(phone);
		if (m.matches()) {
			User user = userService.checkPhoneAvailable(phone);// 绑定该手机的用户
			if (user != null) {
				status = ResponseCodeEnum.ERR_PHONE_USED;
			}
		} else {
			status = ResponseCodeEnum.ERR_PHONE_INVALID;
		}
		return status;
	}

	private ResponseCodeEnum checkPwd(String pwd) throws UnsupportedEncodingException {
		ResponseCodeEnum status = null;
		String pwdFormat = "^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{6,16}$";
		if (!pwd.matches(pwdFormat)) {
			status = ResponseCodeEnum.ERR_PWD_INVALID;
		} else {
			return null;
		}
		return status;
	}

	/*
	 * 验证邀请人是否存在 ，手机格式及是否被占用
	 *
	 * @param phone
	 */
	private ResponseCodeEnum checkInviterPhone(String phone) {
		ResponseCodeEnum status = null;
		String phoneFormat = "^((13[\\d])|(15[0-35-9])|(18[\\d])|(147)|(17[678]))\\d{8}$";
		Pattern p = Pattern.compile(phoneFormat);
		Matcher m = p.matcher(phone);

		if ("null".equals(phone) || "".equals(phone)) {
			logger.info("没有邀请人！！");
		} else if (m.matches()) {
			User tmp_user = userService.checkPhoneAvailable(phone);// 绑定该手机的用户
			if (tmp_user == null) {
				// status = ResponseCodeEnum.ERR_NO_INVETER_PHONE_USER;
			}
		} else {
			// status = ResponseCodeEnum.ERR_NO_INVETER_PHONE_USER;//这里相比老版本code有改动
		}
		return status;
	}

	/**
	 * @param inviter
	 *            邀请人索引 可能是rd_user表中的user_name,mobile_phone,email，base64后的user_id
	 * @return 邀请人
	 * @throws IOException
	 */
	private User getInviter(String inviter) throws IOException {
		if ("".equals(inviter)) {
			return null;
		} else {
			User inviteUser;
			if (Validates.isPhone(inviter)) {
				inviteUser = userService.checkPhoneAvailable(inviter);
			} else if (Validates.isEmail(inviter)) {
				inviteUser = userService.getUserByEmail(inviter);
			} else {
				Base64.Decoder decoder = Base64.getDecoder();
				inviter = new String(decoder.decode(inviter), "utf-8");
				inviteUser = userService.getUserById(Integer.valueOf(inviter));
			}
			return inviteUser;
		}
	}

	/**
	 * 检验验证码
	 * 
	 * @param pool
	 * @param phoneOrEmail
	 * @param code
	 */
	protected ResponseCodeEnum checkCode(Map<String, Object> pool, String phoneOrEmail, String code) {
		ResponseCodeEnum status = null;
		Map varPool = (Map) pool.get(phoneOrEmail);
		if (varPool == null) {
			return ResponseCodeEnum.ACCESS_GET_ERROR;// "请先获取验证码"(这里需要自定义desc)
		}
		long addtime = (Long) varPool.get("addtime");
		long time = System.currentTimeMillis();
		if (addtime - time > 1800000L) {
			return ResponseCodeEnum.ACCESS_TIME_OUT;// "验证码已过期，请重新获取"
		}
		String ex_code = (String) varPool.get("code");
		if (!((ex_code != null) && (ex_code.equals(code)))) {
			return ResponseCodeEnum.ACCESS_ERROR;// "验证码错误"(这里需要自定义desc)
		}
		pool.remove(phoneOrEmail);
		return status;
	}

	/**
	 * redis检验验证码
	 * 
	 * @param code
	 */
	protected ResponseCodeEnum redisCheckCode(String code, String redisKey) {
		if (StringUtil.isBlank(code)) {
			return ResponseCodeEnum.ACCESS_ERROR;
		}
		JSONObject codeObject = redisService.getJsonObjectByKey(redisKey);
		//未获取到redis值，返回提示获取验证码
		if(null == codeObject){
			return ResponseCodeEnum.ACCESS_GET_ERROR;
		}
		String redisCode = codeObject.getString("code");
		if (StringUtil.isBlank(redisCode)) {
			return ResponseCodeEnum.ACCESS_GET_ERROR;
		}
		if (!redisCode.equals(code)) {
			return ResponseCodeEnum.ACCESS_ERROR;
		}
		return null;
	}

	private User loginValidate(String id, String pwd, HttpServletResponse response){
		Response resp = new Response();
		User user = userService.getUserByUserName(id);
		if (user == null) {
			resp.setResponseCode(ResponseCodeEnum.ERR_USER_INVALID);
			Util.sendResponse(JsonUtil.toJson(resp), response);
			return null;
		}
		String pwd2 = user.getPwd();
		if (StringUtils.isBlank(pwd2)) {
			resp.setResponseCode(ResponseCodeEnum.ERR_PWD_NOT_CORRECT,"未设置初始密码，请使用短信验证码登录");
			Util.sendResponse(JsonUtil.toJson(resp), response);
			return null;
		}
		if (!SwordBCrypt.checkpw(pwd, pwd2)) {
			loginFailProtect(user, response);
			return null;
		}
		return user;
	}

	/**
	 *  登录失败处理
	 * @param  user 登录失败的用户
	 * @param response
	 */
	private void loginFailProtect(User user, HttpServletResponse response) {
		Response resp = new Response();
		long now = System.currentTimeMillis();
		// 时间间隔2分钟
		long timeRange = 10 * 1000;
		String tmpLastFailTime = redisService.get("login_fail_last_time:" + user.getMobilePhone());
		Long lastFailTime = null;
		if (!StringUtil.isBlank(tmpLastFailTime)) {
			lastFailTime = Long.parseLong(tmpLastFailTime);
		}
		if (lastFailTime == null) {
			lastFailTime = (long) 0;
		}
		// 上次密码错误时间不到两分钟
		if (now - lastFailTime > timeRange) {
			// 上次密码错误时间超过两分钟（包含第一次密码错误）
			redisService.set("login_fail_last_time:" + user.getMobilePhone(), now + "");
			redisService.expire("login_fail_last_time:" + user.getMobilePhone(), 60 * 10);
			resp.setResponseCode(ResponseCodeEnum.ERR_PWD_NOT_CORRECT, "用户名或密码不正确");
			Util.sendResponse(JsonUtil.toJson(resp), response);
			return;
		}
	}

//	/*
//	 * 根据用户获取token
//	 * @param user
//	 * @return
//	 * @throws Exception
//	 */
//	private String getToken1(User user) throws Exception {
//		String token = "";
//		Map<String, Object> payload = new HashMap<String, Object>();
//		Date date = new Date();
//		payload.put("userId", user.getUserId());// 用户id
//		payload.put("phone", user.getMobilePhone());// 用户手机号
//		payload.put("ext", date.getTime() + 1000 * 60 * 60 * 24 * 7);// 过期时间24*7小时
//		String redisKey = RedisKeyConstant.CONFIG_PRE + "app_jwt_token_secret";
//        ResponseCodeEnum code = null;
//        String secret = redisService.get(redisKey);
//		token = Jwt.createToken(payload, secret);
//		logger.info("====token====:" + token);
//		// 这里使用的是新的token方式
//		return token;
//	}

	/**
	 * 60s内只发一次验证码
	 */
	protected boolean fixedTimeSendCode(Map pool, String phoneOrEmail) {
		boolean flag = false;
		if (pool.containsKey(phoneOrEmail)) {
			Map varPool = (Map) pool.get(phoneOrEmail);
			if (varPool != null) {
				long addtime = (Long) varPool.get("addtime");
				if (System.currentTimeMillis() - addtime < 60000L) {
					flag = true;
				}
			}
		}
		return flag;
	}

	public Boolean redisFixedTimeSendCode(String phone) {
		try {
			String key = "uxq:verification_code:resetPwdCode:" + phone;
			String redisValue = redisService.get(key);
			if (!StringUtil.isBlank(redisValue)) {
				Map<String, String> data = JsonUtil.jsonToMap(redisValue);
				String addTimeStr = data.get("addTime");
				if (!StringUtil.isBlank(addTimeStr)) {
					Long addTime = Long.parseLong(addTimeStr);
					if (addTime != null && (System.currentTimeMillis() - addTime < 60000L)) {
						return true;
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return false;
	}

	private void insertResetPwdCodeToRedis(String phone, String createCode) {
		Map<String, String> data = new HashMap<>();
		String key = "uxq:verification_code:resetPwdCode:" + phone;
		data.put("phone", phone);
		data.put("code", createCode);
		data.put("addTime", String.valueOf(System.currentTimeMillis()));
		redisService.set(key, JsonUtil.toJson(data));
		redisService.expire(key, 60 * 30);
	}

	public void sendCode(String phone, String createCode) throws MsgException {
		try {
			// 注册验证码模版
			String noticeTypeNid = "get_pwd_phone";
			List<MessageTemplate> messageTemplateList = messageTemplateDao.findByNid(noticeTypeNid);
			if (messageTemplateList != null && messageTemplateList.size() > 0) {
				MessageTemplate messageTemplate = messageTemplateList.get(0);
				String tpl_code = messageTemplate.getTplCode();
				// 获取 注册验证码 短信模版内容
				Map<String, Object> sendData = new HashMap<>();
				sendData.put("code", createCode);
				sendData.put("phone", phone);
				// 封装notice类
				Message message = new Message();
				message.setMobile(phone);
				message.setTplId(messageTemplate.getTplId());
				message.setMsgContent(StringUtil.fillTemplet(messageTemplate.getTplContent(), sendData));
				message.setAddTime(new Date());
				messageDao.insert(message);
				// 发送短信方法
				coreNoticeService.sendMessage(message, 1, createCode, tpl_code);
				long nowTime = System.currentTimeMillis();
				logger.info("code:>>>> " + createCode + " addtime:" + nowTime);
			}
		} catch (Exception e) {
			throw new MsgException(ResponseCodeEnum.ERR_SENT_MSG_FAIL, "短信发送失败");
		}
	}

    /**
     * 校验修改密码验证码
     *
     * @throws IOException
     */
    @RequestMapping("/checkModifypassword")
    public void checkModifypassword(@RequestBody UserDTO userDTO, HttpServletResponse response) throws Exception {
        String identifier = userDTO.getMobilePhone();
        String code = userDTO.getCode();
        Response resp = new Response();
        //校验验证码
        String key =RedisKeyConstant.APP_VALIDATE_CODE_PREFIX + SmsPortal.MODIFYPASSWORD_CODE +":" + identifier;
        ResponseCodeEnum status = redisCheckCode(code, key);
        if(status != null){
            resp.setResponseCode(status);
            Util.sendResponse(JsonUtil.toJson(resp),response);
            return;
        }
        //此处增加一个用户的判断，如果用户不存在，则新增，如果存在，则不操作
        User user = new User();
        user.setMobilePhone(identifier);
        User isUser = userService.getUserByMobilePhone(user);
        if(isUser==null){
            isUser = new User();
            isUser.setMobilePhone(identifier);
            isUser.setAddTime(new Date());
			isUser.setUserName(identifier);
			userService.baseInset(isUser);
//            userService.insertReturnUserId(isUser);
            //并且新增一条userInfo
            RdUserInfoEntity userInfoDTO = new RdUserInfoEntity();
            userInfoDTO.setUserId(isUser.getUserId());
            userInfoDTO.setMobilePhone(identifier);
            userInfoDTO.setAddTime(new Date());
            userInfoService.addUserInfo(userInfoDTO);
        }
		//生成用户token，并根据当前系统配置，添加到redis中
		String token = userService.createUserLoginToken(isUser);
        resp.setResponseCode(ResponseCodeEnum.SUCCESSED,"登录成功");
        resp.setRes_data(token);
        Util.sendResponse(JsonUtil.toJson(resp), response);
    }

}
